/**
 * @file none_entry.c
 * @author LokLiang (lokliang@163.com)
 * @brief
 * @version 0.1
 * @date 2023-05-01
 *
 * @copyright Copyright (c) 2023
 *
 */

#include "sys_init.h"

__weak bool sys_log_enable_print(void)
{
    return true;
}

#if !defined(MIX_OS) && !defined(MIX_RTK) && !defined(MIX_K_KIT)

#define _INIT_EXPORT_LEADER(NAME, LEVEL, PRIOR)                           \
    static int __sys_init_fn_##NAME(void)                                 \
    {                                                                     \
        return 0;                                                         \
    }                                                                     \
    __used __section(".s_sys_init_t." #LEVEL "." #PRIOR) sys_init_t const \
        __sys_init_##NAME = {                                             \
            .fn = __sys_init_fn_##NAME,                                   \
            .fn_name = #NAME,                                             \
            .line = __LINE__,                                             \
            .file = __FILE__,                                             \
            .level = LEVEL,                                               \
            .prior = PRIOR,                                               \
    }

#define _MODULE_EXPORT_LEADER(LEVEL)                            \
    __used __section(".sys_module_data." #LEVEL) module_t const \
        __sys_module_leader_##LEVEL = {                         \
            .name = "__sys_module_leader_" #LEVEL,              \
            .obj = NULL,                                        \
            .type = (module_type_t)~0,                          \
            .line = __LINE__,                                   \
            .file = __FILE__,                                   \
    }

_INIT_EXPORT_LEADER(leader_0, 0, 0);  // sys_init_t __sys_init_leader_0
_INIT_EXPORT_LEADER(leader_1, 1, 0);  // sys_init_t __sys_init_leader_1
_INIT_EXPORT_LEADER(leader_e, 9, 99); // sys_init_t __sys_init_leader_e

_MODULE_EXPORT_LEADER(0); // module_t __sys_module_leader_0
_MODULE_EXPORT_LEADER(9); // module_t __sys_module_leader_9

static void _sys_init(const sys_init_t *start, const sys_init_t *end)
{
    while (start < end)
    {
        start->fn();
        start = &start[1];
    }
}

#if defined(MIX_SHELL)

#include "components/shell.h"
#include "board_config.h"

static void _shell_handler(void)
{
    char c;
    while (drv_uart_poll_read(g_board_uart_cons.id, &c) > 0)
    {
        shell_putc(&g_uart_handle_vt100, c);
    }
}

#endif /* #if defined(MIX_SHELL) */

int none_entry(void)
{
    _sys_init(&__sys_init_leader_0, &__sys_init_leader_e);

#if defined(MIX_SHELL)
    int irq = drv_uart_irq_callback_enable(g_board_uart_cons.id, _shell_handler);
    drv_uart_irq_enable(g_board_uart_cons.id, true, false, 15);

    shell_set_prompt(&g_uart_handle_vt100, "sh:/> ");
    sh_putstr_quiet(&g_uart_handle_vt100, "sh version");
    shell_putc(&g_uart_handle_vt100, '\r');
#endif

    extern int app_main(void);
    int flag = app_main();

#if defined(MIX_SHELL)
    while (flag)
    {
        if (irq != 0)
        {
            _shell_handler();
        }
    }

    drv_uart_deinit(g_board_uart_cons.id);

#else
    while (flag)
    {
    }
#endif

    return 0;
}

#endif /* #if !defined(MIX_OS) && !defined(MIX_RTK) && !defined(MIX_K_KIT) */
